<template>
  <div>
    <el-dialog
      v-model="visible"
      title="调试"
      :key="toolID"
      width="1100px"
      center
    >
      <div class="steps-container">
        <el-steps
          :space="500"
          :active="activeStep"
          align-center
          finish-status="success"
          class="custom-steps"
        >
          <el-step title="执行参数" @click="handleStepClick(0)" />
          <el-step title="执行结果" @click="handleStepClick(1)" />
        </el-steps>
      </div>
      <el-form
        v-if="stepValue === 0"
        ref="formRef"
        :rules="rules"
        label-position="right"
        label-width="120px"
        class="mx-2 mt-1"
        :model="addForm"
      >
        <el-form-item
          v-for="(field, index) in debugConfig"
          :key="index"
          :label="field.comment"
          :prop="field.key"
        >
          <el-input
            v-if="field.type === 'text'"
            :disabled="taskInfo.status === 1"
            v-model="addForm[field.key]"
          />
          <el-select
            v-if="field.type === 'list'"
            v-model="addForm[field.key]"
            :multiple="field.multiple"
            filterable
            :disabled="taskInfo.status === 1"
            placeholder="Select"
            style="width: 240px"
          >
            <el-option
              v-for="item in field.valueOption"
              :key="item"
              :label="item"
              :value="item"
            />
          </el-select>
          <el-select
            v-model="addForm[field.key]"
            v-if="field.type === 'select'"
            @change="changeCase(field.case, addForm[field.key])"
            :disabled="taskInfo.status === 1"
            placeholder="请选择"
          >
            <el-option
              v-for="item in field.case"
              :key="item.type"
              :label="item.comment"
              :value="item.type"
            >
            </el-option>
          </el-select>
        </el-form-item>
        <span v-if="selectObject" v-for="item1 in selectObject.data">
          <span v-if="addForm[selectObject.name] === item1.type">
            <el-form-item
              v-for="(item2, index) in item1.value"
              :key="index"
              :label="item2.comment"
              :prop="item2.key"
            >
              <el-input
                v-if="item2.type === 'text'"
                :disabled="taskInfo.status === 1"
                v-model="addForm[item2.key]"
                :key="index"
              />
              <el-radio-group
                v-if="item2.type === 'radio'"
                :key="index"
                v-model="addForm[item2.key]"
              >
                <el-radio
                  v-for="(item3, index) in item2.valueOption"
                  :key="index"
                  :disabled="taskInfo.status === 1"
                  :value="item3.label"
                  >{{ item3.option }}</el-radio
                >
              </el-radio-group>
            </el-form-item>
          </span>
        </span>
        <el-form-item label="运行时间(秒):" prop="runtime">
          <el-input
            v-model.number="addForm.runtime"
            type="number"
            :controls="true"
            :disabled="taskInfo.status === 1"
            :step="1"
            @change="runtimeChange"
            placeholder="请输入运行时间(秒)"
          ></el-input>
        </el-form-item>
      </el-form>
      <div v-if="stepValue === 1">
        <el-row :gutter="12" class="demo-radius">
          <el-col>
            <div class="title">
              任务信息
              <el-button
                @click="taskAction"
                type="primary"
                class="action-button"
                >执 行</el-button
              >
            </div>
            <el-descriptions
              :column="debugConfig.length + 2"
              :border="true"
              direction="vertical"
            >
              <el-descriptions-item align="center" label="任务状态">
                <el-tooltip
                  class="box-item"
                  effect="light"
                  :content="taskInfo.statusMessage"
                  placement="top"
                >
                  <el-tag :type="statusType[taskInfo.status]">{{
                    taskInfo.statusDesc
                  }}</el-tag>
                </el-tooltip>
              </el-descriptions-item>
              <el-descriptions-item
                align="center"
                v-for="(field, index) in debugConfig"
                :key="index"
                :label="field.comment"
                >{{ paraObject[field.key] }}</el-descriptions-item
              >
              <el-descriptions-item align="center" label="运行时间(秒)">{{
                paraObject['runtime']
              }}</el-descriptions-item>
            </el-descriptions>
            <div />
          </el-col>
          <el-col>
            <div class="title">任务反馈</div>
            <resultTool
              :taskID="taskInfo.taskID"
              :status="taskInfo.status"
              :id="toolID"
              :result="debugResult"
            />
            <div />
          </el-col>
        </el-row>
      </div>
      <template v-if="stepValue === 0" #footer>
        <span class="debugToolFooter">
          <el-button  @click="visible = false">取 消</el-button>
          <el-button
            type="primary"
            size="small"
            :disabled="taskInfo.status === 1"
            @click="debugData"
          >
            执 行
          </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>
<script lang="ts" setup>
import { onUnmounted, reactive, ref, watch } from 'vue';
import { emitter } from '@/utils/bus';
import {
  toolDebugDetail,
  toolDebug,
  detailTool,
  getToolOption,
  toolStopDebug,
  toolInstanceDetail
} from '@/api/topo/tools';
import {
  getDescFunc, getCopyDescFunc
} from '@/api/topo/topo';
import { ElMessage } from 'element-plus';
import ResultTool from './resultTool.vue';

const instanceID = ref(null)
const toolInstanceID = ref(0)
const visible = ref(false);
const formRef = ref(null);
const toolID = ref(null);
const activeStep = ref(null);
const stepValue = ref(null);
const debugConfig = ref([]);
const debugResult = ref({});
const paraObject = ref({});
const selectObject = ref({});
let timerId;
let timer2Id;

const emit = defineEmits(['updateData']);
// eslint-disable-next-line no-return-assign
const rules = {
  runtime: [
    { required: true, message: '请输入运行时间', trigger: 'blur' },
    { type: 'number', message: '请输入有效运行时间', trigger: 'blur' },
  ],
};
const addForm = reactive({
  runtime: 10,
});
const taskInfo = reactive({
  statusDesc: '',
  statusMessage: '',
  paraData: '',
  status: 0,
  taskID: 0,
});

const statusType = {
  0: 'info',
  1: '',
  2: 'success',
  3: 'danger',
  4: 'warning',
};

const debugTool = async args => {
  // 查询实例详情
  let res;
  if (args.isCopy === true){
    res = await getCopyDescFunc({ id: args.id, uuid: args.instanceID });
  }else {
    res = await getDescFunc({ id: args.id, uuid: args.instanceID });
  }
  if (res.data.isGenerate!==true){
    ElMessage.warning('工具未生成')
    visible.value = false
    return
  }
  if (res?.data?.toolID==0){
    ElMessage.warning('未查询到工具')
  }

  const instanceInfo = await toolInstanceDetail(res?.data?.tool.ID,res?.data?.ID)
  toolInstanceID.value = instanceInfo.data.ID
 // 查询工具实例
  visible.value=true
  instanceID.value = res.data.ID
  toolID.value = res.data.tool.ID
  const {
    data: { type },
  } = await detailTool(toolID.value);
  await getDetail(toolID.value);
  const {
    data: { tools },
  } = await getToolOption();
  // 初始化 form 键值，和 rules
  tools.forEach(tool => {
    if (tool.type === type) {
      tool.debugConfig.forEach(debugConfig => {
        // 向校验规则内添添加规则
        const ruleList = [];
        // 动态向 addForm 内添加键值
        addForm[debugConfig.key] = paraObject.value[debugConfig.key];
        if (debugConfig.type === 'text') {
          if (debugConfig.required) {
            ruleList.push({
              required: true,
              trigger: 'blur',
              message: debugConfig.comment + '不能为空',
            });
          }
          if (debugConfig.valueRegex) {
            ruleList.push({
              validator: (rule, value, callback) =>
                validateToolField(
                  debugConfig.valueRegex,
                  rule,
                  value,
                  callback,
                ),
              trigger: 'blur',
            });
          }
        } else if (debugConfig.type === 'list') {
          if (!paraObject.value[debugConfig.key]) {
            if (debugConfig.multiple) {
              addForm[debugConfig.key] = [debugConfig.valueOption[0]];
            } else {
              addForm[debugConfig.key] = debugConfig.valueOption[0];
            }
          }
          if (debugConfig.required) {
            ruleList.push({
              required: true,
              message: '请选择' + debugConfig.comment,
              trigger: 'change',
            });
          }
        } else if (debugConfig.type === 'select') {
          // 添加 select 级联子内容
          selectObject.value['data'] = debugConfig.case;
          selectObject.value['name'] = debugConfig.key;
          if (!paraObject.value[debugConfig.key]) {
            addForm[debugConfig.key] = debugConfig.case[0].type;
          }
          if (debugConfig.required) {
            ruleList.push({
              required: true,
              message: '请选择' + debugConfig.comment,
              trigger: 'change',
            });
          }
          // select 下有子集内容
          if (debugConfig.case) {
            debugConfig.case.forEach(subData => {
              if (addForm[debugConfig.key] === subData.type) {
                subData.value?.forEach(subVal => {
                  addForm[subVal.key] = paraObject.value[subVal.key];
                  const subRuleList = [];
                  if (subVal.required) {
                    subRuleList.push({
                      required: true,
                      trigger: 'blur',
                      message: subVal.comment + '不能为空',
                    });
                  }
                  if (subVal.valueRegex) {
                    subRuleList.push({
                      validator: (rule, value, callback) =>
                        validateToolField(
                          subVal.valueRegex,
                          rule,
                          value,
                          callback,
                        ),
                      trigger: 'blur',
                    });
                  }
                  rules[subVal.key] = subRuleList;
                });
              }
            });
          }
        }
        rules[debugConfig.key] = ruleList;
      });
      debugResult.value = tool.debugResult;
      debugConfig.value = tool.debugConfig;
    }
  });
  visible.value = true;
};

const runtimeChange = () => {
  if (addForm.runtime < 10) {
    addForm.runtime = 10;
  }
};

const taskAction = () => {
  // 终止操作
  if (taskInfo.status === 1) {
    ElMessage.info('任务执行中')
    // toolStopDebug(toolID.value).then(res => {
    //   if (!(res instanceof Error)) {
    //     ElMessage.success(res.msg);
    //   }
    // });
  } else {
    toolDebug(toolID.value, {
      instanceID: instanceID.value,
      config: taskInfo.paraData,
      runtime: paraObject.value['runtime'],
    }).then(res => {
      if (!(res instanceof Error)) {
        ElMessage.success('开始执行!');
        stepValue.value = 1;
        const timer2Id = setInterval(()=>{
          const instanceInfo = toolInstanceDetail(toolID.value,instanceID.value).then(res=>{
            toolInstanceID.value = instanceInfo.data.ID
            if (toolInstanceID.value>0){
              clearInterval(timer2Id)
            }
          }).catch(()=>{
            clearInterval(timer2Id)
          })
        },1000)
        getDetail(toolID.value);
      }
    });
  }
};

const getDetail = async id => {
  const {
    data: { ID, status, paraData, statusDesc, message },
  } = await toolDebugDetail(id,toolInstanceID.value);
  taskInfo.statusDesc = statusDesc;
  taskInfo.statusMessage = message;
  taskInfo.paraData = paraData;
  taskInfo.status = status;
  taskInfo.taskID = ID;
  // 任务执行中，开启定时监测
  if (taskInfo.status === 1) {
    timerId = setInterval(() => {
      toolDebugDetail(id,toolInstanceID.value).then(res => {
        taskInfo.statusDesc = res.data.statusDesc;
        taskInfo.statusMessage = res.data.message;
        taskInfo.status = res.data.status;
        if (taskInfo.status != 1) {
          activeStep.value = 2;
          // 清除定时任务
          stopResult();
        }
      });
    }, 2000);
  }
  try {
    if (paraData != '') {
      paraObject.value = JSON.parse(paraData);
      addForm.runtime = paraObject.value['runtime'];
    } else {
      paraObject.value = {};
    }
  } catch (error) {
    console.error('Error parsing JSON:', error.message);
  }
  // 获取工具配置信息
  if (status === 0) {
    stepValue.value = 0;
    activeStep.value = 0;
  } else if (status === 1) {
    stepValue.value = 1;
    activeStep.value = 1;
  } else {
    stepValue.value = 1;
    activeStep.value = 2;
  }
};

const stopResult = () => {
  // 检查是否存在定时任务，然后清除
  if (timerId) {
    clearInterval(timerId);
    timerId = null;
  }
  if (timer2Id){
    clearInterval(timer2Id);
    timer2Id = null;
  }
};

const changeCase = (caseData, key) => {
  caseData.forEach(subData => {
    if (key === subData.type) {
      subData.value?.forEach(subVal => {
        addForm[subVal.key] = '';
        const subRuleList = [];
        if (subVal.required) {
          subRuleList.push({
            required: true,
            trigger: 'blur',
            message: subVal.comment + '不能为空',
          });
        }
        if (subVal.valueRegex) {
          subRuleList.push({
            validator: (rule, value, callback) =>
              validateToolField(subVal.valueRegex, rule, value, callback),
            trigger: 'blur',
          });
        }
        rules[subVal.key] = subRuleList;
      });
    }
  });
};

// 步骤点击事件
const handleStepClick = index => {
  stepValue.value = index;
};

// 校验数据格式
const validateToolField = (valueRegex, rule, value, callback) => {
  if (!valueRegex) {
    return callback();
  }
  const regex = new RegExp(valueRegex);
  if (!regex.test(value)) {
    return callback('数据格式错误');
  }
  return callback();
};

emitter.on('debugTool', debugTool);
onUnmounted(async () => {
  emitter.off('debugTool', debugTool);
});

const debugData = async () => {
  formRef.value.validate(async valid => {
    if (!valid) return;
    try {
      const res = await toolDebug(toolID.value, {
        instanceID: instanceID.value,
        config: JSON.stringify(addForm),
        runtime: addForm.runtime,
      });
      if (res instanceof Error) throw res;
      ElMessage.success('操作成功!');
      stepValue.value = 1;
      const timer2Id = setInterval(async () => {
        try {
          const instanceInfo = await toolInstanceDetail(toolID.value, instanceID.value);
          toolInstanceID.value = instanceInfo.data.ID;
          if (toolInstanceID.value > 0) {
            await getDetail(toolID.value);
            clearInterval(timer2Id);
          }
        } catch (error) {
          clearInterval(timer2Id);
        }
      }, 1000);
    } catch (error) {
    }
  });
};

watch(
  visible,
  () => {
    if (!visible.value) {
      selectObject.value = [];
      activeStep.value = 0;
      debugConfig.value = [];
      if (formRef.value) {
        formRef.value.resetFields();
      }
      toolID.value = null;
      emit('updateData');
      stopResult();
    }
  },
  { immediate: false },
);
</script>
<style lang="scss" scoped>
.steps-container {
  height: 50px; /* 设置容器的固定高度 */
}

.action-button {
  float: right;
  margin-right: 10px;
  margin-bottom: 10px;
}

.demo-radius .title {
  color: var(--el-text-color-regular);
  font-size: 18px;
  margin: 10px 0;
}

.debug-config {
  display: flex;
  align-items: center;
}

.demo-radius .value {
  color: var(--el-text-color-primary);
  font-size: 16px;
  margin: 10px 0;
}
</style>
